<template>
    <n-form ref="formElRef" v-bind="bindFormProps" :model="data">
        <n-grid v-if="useGrid" v-bind="bindGridProps" :collapsed="useAdvanceSearch">
            <template v-for="item in formItems">
                <n-gi v-bind="item.bindGridProps" v-if="item.type !== 'hidden'">
                    <n-form-item v-bind="item.bindItemProps">
                        <m-input v-model:value="data[item.property]" v-bind="item.bindInputProps"> </m-input>
                    </n-form-item>
                </n-gi>
            </template>
            <n-gi v-if="searchProps.search" :suffix="useAdvanceSearch" #="{ overflow }" key="searchBtn" class="search-btn-gi">
                <n-space>
                    <m-button v-if="searchProps.searchBtn" v-bind="searchProps.searchBtn" @click="handleSearch" />
                    <m-button v-if="searchProps.resetBtn" v-bind="searchProps.resetBtn" @click="formMethods.resetForm" />
                    <m-button
                        v-if="searchProps.useAdvance"
                        shape="text"
                        @click="toggleCollapse"
                        class="search-btn-advance"
                        icon-placement="right"
                        :icon="overflow ? 'DownOutlined' : 'UpOutlined'"
                    >
                        {{ overflow ? "展开" : "收缩" }}
                    </m-button>
                </n-space>
            </n-gi>
        </n-grid>
    </n-form>
</template>

<script setup lang="ts">
import type { FormMethodsLocal, FormProps } from "./types"
import type { FormInst } from "naive-ui"
import { MInput } from "@/components/Input"
import { MButton } from "@/components/Button"
import { useFormData } from "./hooks/useFormData"
import { useFormProps } from "./hooks/useFormProps"
import { useSearchForm } from "./hooks/useSearchForm"
import { useFormEvent } from "./hooks/useFormEvent"

const props = withDefaults(defineProps<Partial<FormProps>>(), {
    size: "medium",
    inline: false,
    labelWidth: "auto",
    labelAlign: undefined,
    labelPlacement: "left",
    labelShow: true,
    showFeedback: true,
    gap: 0
})

//console.log(useAttrs())

const emits = defineEmits(["register", "finish", "search", "reset"])

const formElRef = ref<FormInst | null>(null)
const propsRef = ref<Partial<FormProps>>({})
const mergedFormProps = computed((): FormProps => ({ ...props, ...unref(propsRef) }) as FormProps)

const { formItems, bindFormProps, useGrid, bindGridProps } = useFormProps(mergedFormProps)
const { data, getFormData, setFormData, setDefaultFormData, resetForm, initFormData } = useFormData(mergedFormProps)
const formMethods = useFormEvent(formElRef, formItems, { getFormData, setFormData, setDefaultFormData, resetForm })
const { searchProps, useAdvanceSearch, toggleCollapse } = useSearchForm(mergedFormProps)

const handleSearch = () => {
    formMethods
        .validate(errors => {
            if (!errors) {
                emits("search", formMethods.getFormData())
            }
        })
        .catch(() => {})
}

const setProps = (registerProps: Partial<FormProps>) => {
    propsRef.value = registerProps
}

defineExpose(formMethods)
onMounted(() => {
    initFormData()
    const methods: FormMethodsLocal = { ...formMethods, setProps }
    emits("register", methods)
})
</script>

<style lang="less" scoped>
.search-btn-gi {
    padding: 2px 0 0 10px;
}

.search-btn-advance {
    vertical-align: bottom;
}
</style>
